#include<stdio.h> 
#include<fcntl.h> 
#include<unistd.h> 
#include<termios.h> // using the termios.h library
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define ATGM331C_BAUD B9600
#include "parser.h"
#include "data_proc.h"
#define locationInfoFile "location.txt"
#include "serial.h"

int main1()
{ 
     int file, count; 
     if ((file = open("/dev/ttyO4", O_RDWR |  O_NOCTTY |  O_NDELAY))<0) 
     { 
         perror("UART: Failed to open the file. \n"); 
         return -1; 
     } 
     struct termios options; // the termios structure is vital 
     tcgetattr(file, &options); // sets the parameters associated with file 
          // Set up the communications options: 
          // 9600 baud, 8-bit, enable receiver, no modem control lines 
     options.c_cflag = B9600 | CS8 | CREAD | CLOCAL; 
     options.c_iflag = IGNPAR | ICRNL; // ignore partity errors, CR -> newline 
     tcflush(file, TCIFLUSH); // discard file information not transmitted 
     tcsetattr(file, TCSANOW, &options); // changes occur immmediately 
     unsigned char transmit[18] = "Hello BeagleBone!"; // the string to send
    
     count = write(file,&transmit,18);
     if (count<=0) 
     {  // send the string
         
         perror("Failed to write to the output\n"); 
         return -1; 
     }
     else
     {
         printf("write %d bytes to com port\n",count);
     }

     usleep(100000); // give the Arduino a chance to respond 
     unsigned char receive[100]; // declare a buffer for receiving data 
     if ((count = read(file, (void*)receive, 100))<0) 
     {  // receive the data 
         if(errno == EAGAIN)
         {
            printf("reading is blocked\n");
         } 
         perror("Failed to read from the input\n"); 
         return -1; 
     } 
     if (count==0) 
         printf("There was no data available to read! \n"); 
     else 
     { 
         printf("The following was read in [%d]: %s\n",count,receive); 
     } 
     close(file); 
     return 0; 
}

void procStrFromUart2(char * buff, int sizeRecv, int fd_file)
{
  char buffStr[1024];
  char plaintext[128];
  ggaInfo stGgaInfo;
  int indexTenthComma;
  int checkRet = checkHead(buff, sizeRecv);
  if(checkRet == GGA)
  {
    unsigned char usrKey[16] = {0};
    unsigned char ciphertext[64] = {0};
    memset(&stGgaInfo, 0, sizeof(ggaInfo));
    parseGGA(buff, sizeRecv, &stGgaInfo);
    printf("len=%d,%s\n",sizeRecv,buff);
    memset(buffStr,0,1024);
    formatGgaStr(&stGgaInfo,buffStr); 
    memset(plaintext,0,128);
    indexTenthComma =  findTenthComma(buff, sizeRecv);   
    if(indexTenthComma == -1)
    {
      memcpy(plaintext,buff,64);   
    }
    else
    {
      int remain = 64 - indexTenthComma-1;
      memcpy(plaintext,buff,indexTenthComma+1);
      memset(plaintext+indexTenthComma+1,',',remain); 
    }
    printf("len plain[%d],%s\n",strlen(plaintext),plaintext);
    getUserKey(usrKey);
    aes128_enc_64bytes(usrKey,plaintext,ciphertext);
    memcpy(plaintext,ciphertext,64);
    printf("len cipher[%d],%s\n",strlen(plaintext),plaintext);
    if(fd_file!=-1)
    {
//	 formatHexStr(buff,sizeRecv,buffStr);
         write(fd_file,buffStr,strlen(buffStr)+1); 

     // write(fd_file,buff,sizeRecv); 
    }
  }  
   
}

void * comRecvThreadProc(void * lpParam)
{
   param_com * pstParam = (param_com*)lpParam;
   int fd_uart = pstParam->fd_uart;
   char * buff = pstParam->buff;
   int fd_file = pstParam->fd_file;
   int count = 0;
   if((fd_uart==-1)||(buff==NULL))
   {
       return;
   }
    
   while(1)
   {
	   memset(buff,0,1024);
      count = read(fd_uart, (void*)buff, 100);
      if (count>0) 
      {  // receive the data 
        //buff[count - 1] = '\0';
        //buff[count] = '\n';
        //printf("com recv data,count[%d], %s\n",count,buff);
        procStrFromUart2(buff, count, fd_file);
      }
      usleep(20);
   }
}
int main(int argc, char *argv[])
{
     int fd_uart; 
     int fd_file;
     pthread_t handle_comRecv;
     char buff[1024];
     void * res;
     if ((fd_uart = open("/dev/ttyO2", O_RDWR |  O_NOCTTY |  O_NDELAY))<0) 
     { 
         perror("UART: Failed to open the file. \n"); 
         return -1; 
     } 

     fd_file = open(locationInfoFile,O_RDWR|O_CREAT|O_TRUNC);
     struct termios options; // the termios structure is vital 
     tcgetattr(fd_uart, &options); // sets the parameters associated with file 
          // Set up the communications options: 
          // 115200  baud, 8-bit, enable receiver, no modem control lines 
     options.c_cflag = B9600 | CS8 | CREAD | CLOCAL;// ATGM331C_BAUD 
     options.c_iflag = IGNPAR | ICRNL; // ignore partity errors, CR -> newline 
     tcflush(fd_uart, TCIFLUSH); // discard file information not transmitted 
     tcsetattr(fd_uart, TCSANOW, &options); // changes occur immmediately 
     cfsetispeed(&options,B9600);
     cfsetospeed(&options,B9600); 
     param_com threadParam;
     threadParam.fd_file =fd_file;
     threadParam.fd_uart =fd_uart;
     threadParam.buff = buff;    
     pthread_create(&handle_comRecv,NULL,comRecvThreadProc,&threadParam);
     
     pthread_join(handle_comRecv,&res);
     free(res); 
     if(fd_uart!=-1)
     {
        close(fd_uart);
        fd_uart = -1;
     }
     
     if(fd_file != -1)
     {
        close(fd_file);
        fd_file = -1;
     }   
}
